package client;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import common.consts.Consts;
import common.consts.MsgPush;
import domain.PushMessage;
import net.minidev.json.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import util.MessageFactory;
import wrapper.push_message.MessageEntity;


import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * Created by chpengzh <cpz@youjianghr.com> on 2015/7/17.
 */
@Component
@JsonSerialize(include= JsonSerialize.Inclusion.NON_DEFAULT)
public class PushMessageClient implements MsgPush {

    private static final ObjectMapper MAPPER = new ObjectMapper();
    private static final Logger LOGGER = LoggerFactory.getLogger(PushMessageClient.class);

    private MessageEntity messageEntity;
    private PushMessage message;
    private String mode;

    public PushMessageClient(){}
    public PushMessageClient(PushMessage message, String mode) {
        this.message = message;
        this.mode = mode;
    }

    //!!构造了一个PushMessageClient后，
    // 直接调用这个方法发送信息!!
    public void send() {
        //post报文内容
        ByteArrayOutputStream out= new ByteArrayOutputStream();
        String post_body = "{}";
        try {
            MAPPER.getSerializationConfig().withSerializationInclusion(JsonInclude.Include.NON_NULL);
            MAPPER.writeValue(out, MessageFactory.create(this.getMessage(), this.getMode()));
            post_body = out.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //post报头:签名内容
        String my_sign = mySign(post_body);
        String res = doPost(post_body, my_sign);
        LOGGER.debug(res);
    }

    //生成友盟推送服务所需要的签名。详见文档附录k
    private String mySign(String post_body) {
        String method = "POST";
        String url = UmengURL;
        String app_master_secret = AppMasterSecret;
        return DigestUtils.md5Hex(method + url + post_body + app_master_secret).toLowerCase();
    }

    //向umeng客户端发送post请求。
    private String doPost(String post_body, String my_sign) {

        String url;
        if (ProxyMode) {
            url = ProxyURL + "?sign=" + my_sign;
        } else {
            url = UmengURL + "?sign=" + my_sign;
        }

        LOGGER.debug("sign={}, and post={}", my_sign, post_body);
        LOGGER.debug("Post Request to {}", url);
        System.out.println("\nsign="+my_sign+"\n\npost="+post_body);

        String body = post_body;
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        post.setEntity(new ByteArrayEntity(body.getBytes()));
        try {
            CloseableHttpResponse response = client.execute(post);
            HttpEntity entity = response.getEntity();
            String ret = EntityUtils.toString(entity, "UTF-8");
            System.out.println(ret);
            return ret;
        } catch (IOException e) {
            LOGGER.error("", e.getMessage());
            System.out.println("[error]"+e.getMessage());
            return "[Fail]:" + e.getMessage();
        }
    }

    public PushMessage getMessage() {
        return message;
    }

    public void setMessage(PushMessage message) {
        this.message = message;
    }

    public String getMode() {
        return mode;
    }

    public void setMode(String mode) {
        this.mode = mode;
    }

    public MessageEntity getMessageEntity() {
        return messageEntity;
    }

    public void setMessageEntity(MessageEntity messageEntity) {
        this.messageEntity = messageEntity;
    }


}
